/*
 * (C) Copyright 2006-2010 Nuxeo SAS (http://nuxeo.com/) and contributors.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser General Public License
 * (LGPL) version 2.1 which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/lgpl.html
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * Contributors:
 *     bstefanescu
 */
package org.nuxeo.gwt.habyt.app.client.form;

import java.io.Serializable;

import org.nuxeo.gwt.habyt.app.client.Application;
import org.nuxeo.gwt.habyt.app.client.form.validators.Validator;
import org.nuxeo.gwt.habyt.templates.client.Constants;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.dom.client.Element;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HasName;
import com.google.gwt.user.client.ui.Widget;

/**
 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
 * 
 */
public abstract class FormControl extends Composite implements Constants {

    /**
     * The owner form
     */
    protected FormWidget form;

    protected String label;

    protected String errorMessage;

    protected Validator validator;

    /**
     * An object set by the form handler when an error occurred
     */
    protected Object error;

    public FormControl(Widget widget) {
        initWidget(widget);
    }

    public void setError(Object error) {
        this.error = error;
    }

    public Object getError() {
        return error;
    }

    public String getLabel() {
        return label;
    }

    public void setLabel(String label) {
        this.label = label;
    }

    public void setErrorMessage(String errorMessage) {
        this.errorMessage = errorMessage;
    }

    public String getErrorMessage() {
        return errorMessage;
    }

    public FormWidget getForm() {
        return form;
    }

    public void setValidator(Validator validator) {
        this.validator = validator;
    }

    public Validator getValidator() {
        return validator;
    }

    @Override
    public Widget getWidget() {
        return super.getWidget();
    }

    public String getName() {
        if (getWidget() instanceof HasName) {
            return ((HasName) getWidget()).getName();
        } else {
            return getWidget().getElement().getPropertyString("name");
        }
    }

    public abstract Serializable getValue();

    public abstract void setValue(Serializable value);

    public boolean validate() {
        if (validator != null) {
            return validator.validate(this);
        }
        return true;
    }

    public void bind() {
        Element element = getElement();
        element.setPropertyObject(THIS, this);
        if (form == null) {
            form = Application.getForm(element);
            if (form != null) {
                form.addControl(this);
            }
        }
    }

    public void unbind() {
        if (form != null) {
            form.removeControl(this);
        }
    }

    @Override
    protected void onLoad() {
        bind();
    }

    @Override
    protected void onUnload() {
        unbind();
    }

    public static native JavaScriptObject createJsForm(Form form) /*-{
                                                                  return {        
                                                                  submit: function() { 
                                                                  form.@org.nuxeo.gwt.habyt.app.client.form.Form::submit()(); 
                                                                  },
                                                                  reset: function() { 
                                                                  form.@org.nuxeo.gwt.habyt.app.client.form.Form::reset()(); 
                                                                  },
                                                                  validate: function() { 
                                                                  form.@org.nuxeo.gwt.habyt.app.client.form.Form::validate()();
                                                                  }, 
                                                                  element: function(name) { 
                                                                  return form.@org.nuxeo.gwt.habyt.app.client.form.Form::getControlElement(Ljava/lang/String;)(name); 
                                                                  },
                                                                  // builtin validators
                                                                  checkRegex: function(expr, value, message) {

                                                                  },
                                                                  checkRequired: function(value, message) {

                                                                  },
                                                                  checkRange: function(min, max, value, message) {

                                                                  },
                                                                  checkLength: function(min, max, value, message) {

                                                                  },
                                                                  checkEquals: function(refControl, value, message) {

                                                                  },
                                                                  checkPassword: function(refPassword, value, message) {

                                                                  }        
                                                                  };
                                                                  }-*/;

}
